﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UM_SERVER.Timer
{
    /// <summary>
    ///     提供了所需超时事件的TO_Timer包装类
    /// </summary>
    abstract class TimeOutEvent : IMetaData
    {
        /// <summary>
        ///     超时委托
        /// </summary>
        protected delegate void PUBLIC_DELEGATE();
        /// <summary>
        ///     运行标志位
        /// </summary>
        private int RunFlag = 0;
        /// <summary>
        ///     内部包含的TO_Timer对象
        /// </summary>
        protected TO_Timer timer = new TO_Timer();
        /// <summary>
        ///     提供了公共操作的超时计算与处理
        /// </summary>
        /// <param name="Key" type="string">
        ///     <para>
        ///         超时器的唯一标示
        ///     </para>
        /// </param>
        /// <param name="Interval" type="int">
        ///     <para>
        ///         超时器触发间隔 [单位: 毫秒]
        ///     </para>
        /// </param>
        /// <param name="TryCount" type="int">
        ///     <para>
        ///         超时器总共重试次数,如果为-1则代表永久尝试
        ///     </para>
        /// </param>
        public TimeOutEvent(String Key, int Interval, int TryCount)
        {
            this.timer.TryCount = TryCount;
            this.timer.Interval = Interval;
            this.Key = Key;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.TimeOut += new EventHandler<EventArgs>(timer_TimeOut);
        }

        void timer_TimeOut(object sender, EventArgs e)
        {
            OnOnTryFull(new EventArgs());
            //移除当前Timer事件，从Timer事件集合中
            Globle.timeoutTimerManager.RemoveTimer(this);
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //确保第一次不执行，等到第二次触发间隔到后，还是计算执行
            if (this.RunFlag > 0)
            {
                OnOnTick(new EventArgs());
                if (this.timer.TryCount > 0)
                {
                    if (this.timer.TryIndex < this.timer.TryCount)
                    {
                        this.timer.TryIndex++;
                    }
                    else
                    {
                        OnOnTryFull(new EventArgs());
                        //移除当前Timer事件，从Timer事件集合中
                        Globle.timeoutTimerManager.RemoveTimer(this);
                    }
                }
                //永久尝试
                else
                {
                    OnOnTick(new EventArgs());
                }
            }
            else
            {
                this.RunFlag++;
            }
        }

        /// <summary>
        ///     得到当前超时计时器事件类的Timer对象
        /// </summary>
        /// <returns>
        ///     返回Timer对象
        /// </returns>
        public TO_Timer CurrentTimer()
        {
            return timer;
        }

        /// <summary>
        ///     重置当前超时器
        /// </summary>
        public void ReSet()
        {
            this.timer.Stop();
            this.RunFlag = 0;
            this.timer.Start();
        }



        #region IMetaData 成员

        private String key;
        public string Key
        {
            get
            {
                return key;
            }
            set
            {
                key = value;
            }
        }

        #endregion

        #region 'OnTick' event definition code

        // Private delegate linked list (explicitly defined)
        private EventHandler<System.EventArgs> OnTickEventHandlerDelegate;

        /// <summary>
        ///     TODO: Describe the purpose of this event here
        /// </summary>
        public event EventHandler<System.EventArgs> OnTick
        {
            // Explicit event definition with accessor methods
            add
            {
                OnTickEventHandlerDelegate = (EventHandler<System.EventArgs>)Delegate.Combine(OnTickEventHandlerDelegate, value);
            }
            remove
            {
                OnTickEventHandlerDelegate = (EventHandler<System.EventArgs>)Delegate.Remove(OnTickEventHandlerDelegate, value);
            }
        }

        /// <summary>
        ///     This is the method that is responsible for notifying
        ///     receivers that the event occurred
        /// </summary>
        protected virtual void OnOnTick(System.EventArgs e)
        {
            if (OnTickEventHandlerDelegate != null)
            {
                OnTickEventHandlerDelegate(this, e);
            }
        }

        #endregion //('OnTick' event definition code)

        #region 'OnTryFull' event definition code

        // Private delegate linked list (explicitly defined)
        private EventHandler<System.EventArgs> OnTryFullEventHandlerDelegate;

        /// <summary>
        ///     TODO: Describe the purpose of this event here
        /// </summary>
        public event EventHandler<System.EventArgs> OnTryFull
        {
            // Explicit event definition with accessor methods
            add
            {
                OnTryFullEventHandlerDelegate = (EventHandler<System.EventArgs>)Delegate.Combine(OnTryFullEventHandlerDelegate, value);
            }
            remove
            {
                OnTryFullEventHandlerDelegate = (EventHandler<System.EventArgs>)Delegate.Remove(OnTryFullEventHandlerDelegate, value);
            }
        }

        /// <summary>
        ///     This is the method that is responsible for notifying
        ///     receivers that the event occurred
        /// </summary>
        protected virtual void OnOnTryFull(System.EventArgs e)
        {
            if (OnTryFullEventHandlerDelegate != null)
            {
                OnTryFullEventHandlerDelegate(this, e);
            }
        }

        #endregion //('OnTryFull' event definition code)

    }
}
